package gdbc

import (
	"context"
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"time"
)

/*
MySQL: github.com/go-sql-driver/mysql

PostgreSQL: github.com/lib/pq

SQLite: github.com/mattn/go-sqlite3

SQL Server: github.com/denisenkom/go-mssqldb
*/

func InitDb() *sql.DB {
	db, err := sql.Open("mysql", "root:fan@1988fan@1988fan@1988fan@1988@tcp(127.0.0.1:3306)/gdbc")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 设置最大打开连接数
	db.SetMaxOpenConns(25)

	// 设置最大空闲连接数
	db.SetMaxIdleConns(25)

	// 设置连接最大存活时间
	db.SetConnMaxLifetime(5 * time.Minute)

	// 验证连接是否有效
	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}

	return db
}

func Query(db *sql.DB) {
	// 查询多行
	rows, err := db.Query("SELECT id, name FROM sys_user WHERE mobile = ?", "23")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	for rows.Next() {
		var id int
		var name string
		if err := rows.Scan(&id, &name); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("id: %d, name: %s\n", id, name)
	}

	// 检查查询过程中是否有错误
	if err = rows.Err(); err != nil {
		log.Fatal(err)
	}

	// 查询单行
	var name string
	err = db.QueryRow("SELECT name FROM sys_user WHERE id = ?", 1).Scan(&name)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(name)
}

func PrepareQuery(db *sql.DB) {
	stmt, err := db.Prepare("SELECT name FROM sys_user WHERE id = ?")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()

	rows, err := stmt.Query(1)
	// 处理rows...
	if err != nil {
		log.Fatal(err)
	}

	defer rows.Close()

	for rows.Next() {
		var id int
		var name string
		if err := rows.Scan(&id, &name); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("id: %d, name: %s\n", id, name)
	}

}

func QueryContext(db *sql.DB) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	// 带上下文的查询
	rows, err := db.QueryContext(ctx, "SELECT * FROM sys_user")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
}

func Update(db *sql.DB) {
	// 插入数据
	result, err := db.Exec("INSERT INTO sys_user(name, age) VALUES(?, ?)", "Alice", 25)
	if err != nil {
		log.Fatal(err)
	}

	// 获取最后插入的ID
	lastInsertID, err := result.LastInsertId()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(lastInsertID)

	// 获取影响的行数
	rowsAffected, err := result.RowsAffected()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(rowsAffected)
}

func RunTx(db *sql.DB) {
	tx, err := db.Begin()
	if err != nil {
		log.Fatal(err)
	}

	// 在事务中执行操作
	_, err = tx.Exec("UPDATE sys_user SET balance = balance - ? WHERE id = ?", 100, 1)
	if err != nil {
		tx.Rollback()
		log.Fatal(err)
	}

	_, err = tx.Exec("UPDATE sys_user SET balance = balance + ? WHERE id = ?", 100, 2)
	if err != nil {
		tx.Rollback()
		log.Fatal(err)
	}

	// 提交事务
	err = tx.Commit()
	if err != nil {
		log.Fatal(err)
	}
}
